from django.db import models
from django.db.models.query import QuerySet
from django.db.models.fields import related

from tppt.lib import actions

class Model(models.Model):
	class Meta:
		abstract = True
	
	def __unicode__(self):
		if hasattr(self, 'short'):
			return self.short
		elif hasattr(self, 'name'):
			return self.name
		else:
			return "<%s object>" % self.__class__.__name__
	
	@classmethod
	def get_fields_dict(cls):
		res={}
		for field in cls._meta.fields + cls._meta.many_to_many:
			res[field.name]=field
		return res
	@classmethod
	def get_list_fields(cls):
		names=cls._meta.admin.list_display
		if names==['__str__']:
			names=cls.get_fields_dict().keys()
		fields=cls.get_fields_dict()
		return [fields[x] for x in names]
	@classmethod
	def get_m2m_field_name_from_mgr(cls,mgr):
		join_table=mgr.join_table.replace('`', '')
		for fld in cls._meta.many_to_many:
			if join_table==fld.m2m_db_table():
				return fld
		return None
	
	@classmethod
	def get_query_set_actions(cls):
		return ['index', 'delete_all']
	@classmethod
	def get_query_set_action(cls, name, entity_set):
		from tppt.lib.actions import model as model_actions
		if name == 'index':
			return model_actions.IndexAction(entity_set)
		elif name == 'delete_all':
			return model_actions.DeleteAllAction(entity_set)
		return None
	def get_actions(self):
		res=['details', 'delete']
		model=self.__class__
		if hasattr(model._meta, 'actions') and model._meta.actions.inner_objects:
			res.append('getin')
		return res
	def get_action(self, name):
		from tppt.lib.actions import model as model_actions
		if name == 'details':
			import tppt.lib.actions.model.details
			return tppt.lib.actions.model.details.Action(self)
		elif name == 'delete':
			return model_actions.DeleteAction(self)
		elif name == 'getin':
			return model_actions.GetInAction(self)
		
	def get_details_sections(self):
		from tppt.lib.actions.model.details import PropertyListSection
		from tppt.lib.actions.model.details import ActionsSection
		from tppt.lib.actions.model.details import ReferringEntitiesSection
		res=[PropertyListSection(), ActionsSection()]
		for ref_model, ref_fld in self.get_related_keys():
			res.append(ReferringEntitiesSection(ref_model, ref_fld))
		return res
	
	@classmethod
	def register_related_key(cls,model,field):
		if not hasattr(cls, '_related_keys'):
			cls._related_keys=[]
		cls._related_keys.append((model, field))
	@classmethod
	def get_related_keys(cls):
		if not hasattr(cls, '_related_keys'):
			return []
		return cls._related_keys
		
	
actions.register_action_getter(Model, lambda obj, name: obj.get_action(name), 
							lambda obj: obj.get_actions(), class_getter=True)
actions.register_action_getter(QuerySet, lambda obj, name: obj.model.get_query_set_action(name, obj), 
							lambda obj: obj.model.get_query_set_actions(), class_getter=True)

def get_reg_rel_proc():
	parent=related.ForeignKey.contribute_to_related_class
	def reg_rel_proc(self, cls, related):
		parent(self, cls, related)
		cls.register_related_key(related.model, related.field)
	return reg_rel_proc

related.ForeignKey.contribute_to_related_class=get_reg_rel_proc()


    
class Actions(object):
	inner_objects=None
	
	def __init__(self, **kwargs):
		#from django.db.models import manager 
		#self.manager = manager or Manager()
		self.__dict__.update(kwargs)

	@classmethod
	def contribute_to_class(self, cls, name):
		""" complicated beast, takes in the contribute call from the django base 
		class construction, generates an instance of this class and fills it with 
		the parameters being globals in the class definition in a model. """

		cls._meta.actions = Actions(**dict([(k, v) for k, v in self.__dict__.items() if not k.startswith('_')]))	
		# Make sure our manager/form classes have access to the model
		#cls._meta.actions.manager.model = cls 
 	 	